package com.whpost.api.controller.login;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.whpost.api.config.MySessionContext;
import com.whpost.api.entity.ReqLogin;

import com.whpost.api.utils.ApiUtils;
import com.whpost.service.dao.t.TCzyDao;
import com.whpost.service.entity.t.TCzy;
import com.whpost.service.entity.tools.ResultInfo;
import com.whpost.service.tools.Aes;
import com.whpost.service.tools.ToolBean;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.crypto.NoSuchPaddingException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;

/**
 * @author Yinzhuoyi
 * @date 2020/5/11 15:22
 */
@RestController
public class LoginController {

    @Resource
    private TCzyDao tCzyDao;

    @Resource
    DefaultKaptcha defaultKaptcha;
    /**
     *
     * @param reqLogin
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    @RequestMapping(value ="loginDo")
    public ResultInfo loginDo(@RequestBody ReqLogin reqLogin, HttpServletRequest httpServletRequest) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {

        TCzy tCzy = new TCzy();
        if (null==reqLogin){
            return new ResultInfo(500, "用户名称或密码错误！",null);
        }else{
            //创建MySessionContext对象
            MySessionContext myContext = MySessionContext.getInstance();
            //根据sessionId获取session
            ToolBean.info("sessionId:"+reqLogin.getSid());
            HttpSession httpSession = myContext.getSession(reqLogin.getSid());
            ToolBean.info("获取到的session:"+httpSession);
            String s_code=ToolBean.ntos((String)httpSession.getAttribute("vcode")).toUpperCase();
            //删除session
            myContext.DelSession(httpSession);
            String checkCode = reqLogin.getRadomyzm().toUpperCase();

            ToolBean.info("httpServletRequest:"+httpServletRequest.getRequestURI());
            ToolBean.info("checkCode:"+checkCode);
            ToolBean.info("reg_code:"+s_code);
            if(!s_code.equals(checkCode)){
                return new ResultInfo(10, "验证码错误！",null);
            }
            String dlmc = reqLogin.getDlmc();
            String mm = reqLogin.getMm();
            if ("".equals(dlmc) || "".equals(mm)) return new ResultInfo(500, "用户名称或密码错误！",null);

            tCzy = tCzyDao.getUseByDlmc(dlmc);
            if (null == tCzy)
            {
                return new ResultInfo(500, "用户名称或密码错误！",null);
            }else {
                if (!"1".equals(tCzy.getState())) {
                    return new ResultInfo(500, "用户已经删除！",null);
                } else {
                    mm = new String(ToolBean.decode(mm));
                    String mmMd5 = ToolBean.getMD5Str(mm);
                    String db_password = tCzy.getPwd();
                    if (!("".equals(db_password) && "".equals(mm)) && !db_password.equals(mmMd5)) {
                        return new ResultInfo(500, "用户名称或密码错误！",null);
                    } else {
                        if (null == tCzy.getXzjgId()) {
                            return new ResultInfo(500, "该用户没有绑定机构，无法登陆！",null);
                        }
                        if (ToolBean.getMD5Str("111111").equals(db_password)) {
                            String str = tCzy.getDlmc()+"|"+String.valueOf(tCzy.getId());
                            return new ResultInfo(11, "需要修改初始密码！",ToolBean.getEncode(str));
                        }
                        //如果用户没有秘钥，补充秘钥
                        if (StringUtils.isEmpty(tCzy.getAeskey()) || StringUtils.isEmpty(tCzy.getAesiv())){
                            tCzy.setAeskey(ToolBean.getRandomString(16));
                            tCzy.setAesiv("0102030405060708");
                            tCzyDao.updateById(tCzy);
                        }
                        //校验完，准备登录，浏览器关闭后，token失效
                        StpUtil.login(tCzy.getId(),false);
                        // 第2步，获取 Token  相关参数
                        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
                        // 第3步，返回给前端
                        String token = tokenInfo.getTokenValue();
                        String data = "{\"code\":\"200\",\"token\":\"" + token + "\",\"a\":\"" + tCzy.getAeskey() + "\",\"b\":\"" + tCzy.getAesiv() + "\",\"c\":\"" + tCzy.getId() + "\"}";
                        ToolBean.info("登录成功，准备加密后返回的字符串:"+data);
                        String rtnStr = Aes.encrypt(data,"NLfZ3aIOg77E2rT8");
                        return new ResultInfo(200, "登录成功！",rtnStr);
                    }
                }
            }
        }
    }

    /**
     *
     * @param reqLogin
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    @RequestMapping(value ="loginDoApp")
    public ResultInfo loginDoApp(@RequestBody ReqLogin reqLogin) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
        TCzy tCzy = new TCzy();
        if (null==reqLogin){
            return new ResultInfo(500, "用户名称或密码错误！",null);
        }else{
            String dlmc = reqLogin.getDlmc();
            String mm = reqLogin.getMm();
            if ("".equals(dlmc) || "".equals(mm)) return new ResultInfo(500, "用户名称或密码错误！",null);

            tCzy = tCzyDao.getUseByDlmc(dlmc);
            if (null == tCzy)
            {
                return new ResultInfo(500, "用户名称或密码错误！",null);
            }else {
                if (!"1".equals(tCzy.getState())) {
                    return new ResultInfo(500, "用户已经停用！",null);
                } else {
                    String mmMd5 = ToolBean.getMD5Str(mm);
                    String db_password = tCzy.getPwd();
                    ToolBean.info("输入的密码:"+mm);
                    ToolBean.info("输入的密码MD5:"+mmMd5);
                    ToolBean.info("数据库的密码:"+db_password);
                    if (!("".equals(db_password) && "".equals(mm)) && !db_password.equals(mmMd5)) {
                        return new ResultInfo(500, "用户名称或密码错误！",null);
                    } else {
                        if (null == tCzy.getXzjgId()) {
                            return new ResultInfo(500, "该用户没有绑定机构，无法登陆！",null);
                        }
                        //如果用户没有秘钥，补充秘钥
                        if (StringUtils.isEmpty(tCzy.getAeskey()) || StringUtils.isEmpty(tCzy.getAesiv())){
                            tCzy.setAeskey(ToolBean.getRandomString(16));
                            tCzy.setAesiv("0102030405060708");
                            tCzyDao.updateById(tCzy);
                        }
                        //校验完，准备登录
                        StpUtil.login(tCzy.getId());
                        // 第2步，获取 Token  相关参数
                        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
                        // 第3步，返回给前端
                        String token = tokenInfo.getTokenValue();
                        String data = "{\"code\":\"200\",\"token\":\"" + token + "\",\"a\":\"" + tCzy.getAeskey() + "\",\"b\":\"" + tCzy.getAesiv() + "\",\"c\":\"" + tCzy.getId() + "\"}";
                        ToolBean.info("登录成功，准备加密后返回的字符串:"+data);
                        String rtnStr = Aes.encrypt(data,"NLfZ3aIOg77E2rT8");
                        return new ResultInfo(200, "登录成功！",rtnStr);
                    }
                }
            }
        }
    }

    /**
     *
     * @return
     */
    @SaCheckLogin
    @RequestMapping(value ="check_login")
    public ResultInfo checkLogin() {
        String loginId = ApiUtils.getLoginId();
        return new ResultInfo(200, "服务正常！",null);
    }

    /**
     * 验证码 防刷未做
     * @param httpServletRequest
     * @param httpServletResponse
     * @throws Exception
     */
    @RequestMapping("vcode")
    public Map<String,Object> getVcode(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        byte[] captchaChallengeAsJpeg = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            String ip = ToolBean.getIpAddress(httpServletRequest);
            ToolBean.info("ip:"+ip+"在访问vcode");
            //创建MySessionContext对象
            MySessionContext myContext = MySessionContext.getInstance();
            // 生产验证码字符串并保存到session中
            String createText = defaultKaptcha.createText();
            HttpSession httpSession = httpServletRequest.getSession();
            httpSession.setAttribute("vcode", createText);
            //存储session
            myContext.AddSession(httpSession);
            // 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
            BufferedImage challenge = defaultKaptcha.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
            byte[] imageBytes = jpegOutputStream.toByteArray();
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            Map<String,Object> infoMap = new HashMap<>();
            infoMap.put("sid",httpSession.getId());
            infoMap.put("yzm",base64Image);
            return infoMap;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return null;
        }
    }

    /**
     *
     * @return
     */
    @RequestMapping(value ="xgmm")
    public ResultInfo xgmm(@RequestBody Map<String, Object> map) {
        String dec_data = Aes.decrypt((String)map.get("data"),"NLfZ3aIOg77E2rT8");
        JSONObject jsonObject = JSONObject.parseObject(dec_data);
        String id = jsonObject.getString("id");
        String str = ToolBean.getDecode(id);
        ToolBean.info("初始密码修改："+str);
        String old_pwd = jsonObject.getString("old_pwd");
        String new_pwd = jsonObject.getString("new_pwd");
        String new_pwd1 = jsonObject.getString("new_pwd1");
        String str1[] = str.split("\\|");
        if (str1.length!=2){
            return new ResultInfo(500, "数据不正确！",null);
        }
        TCzy tCzy = tCzyDao.selectById(str1[1]);
        if (null==tCzy){
            return new ResultInfo(500, "没有操作员信息！",null);
        }
        old_pwd = ToolBean.getMD5Str(old_pwd);
        if (!old_pwd.equals(tCzy.getPwd()))
        {
            return new ResultInfo(500,"原密码错误！",null);
        }
        if(StringUtils.isEmpty(new_pwd))
        {
            return new ResultInfo(500,"新密码不能为空！",null);
        }
        if(!new_pwd.equals(new_pwd1))
        {
            return new ResultInfo(500,"新密码两次输入不一致！",null);
        }
        if (!ToolBean.checkPassWordIsStrong(new_pwd))
        {
            return new ResultInfo(500,"密码限制8-20位，要求大小写字母、数字、特殊符号至少包含两种!",null);
        }
        new_pwd = ToolBean.getMD5Str(new_pwd);
        int a = tCzyDao.updateUserPwd(new_pwd,String.valueOf(tCzy.getId()));
        if (a>0)
        {
            return new ResultInfo(0,"修改成功！",null);
        }else{
            return new ResultInfo(500,"用户信息不存在！",null);
        }
    }
}
